package com.sunwayworld.basemodule.common.utils;

import com.deepoove.poi.data.HyperlinkTextRenderData;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.policy.TextRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.util.StyleUtils;
import com.deepoove.poi.util.TableTools;
import com.deepoove.poi.xwpf.XWPFParagraphWrapper;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.VerticalAlign;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author hongp@sunwayworld.com 2020年12月17日
 */
public class LimsTextRenderPolicy extends TextRenderPolicy {

    //上标
    private static final String SUP_MARK_START = "<sup>";
    private static final String SUP_MARK_END = "</sup>";
    //下标
    private static final String SUB_MARK_START = "<sub>";
    private static final String SUB_MARK_END = "</sub>";
    private static final String SUB_MARK_REG = "</?su[b,p]>";

    @Override
    public void doRender(RenderContext<Object> context) throws Exception {
        Helper.renderTextRun(context.getRun(), context.getData());
    }

    public static class Helper {

        public static final String REGEX_LINE_CHARACTOR = "\\n";

        public static void renderTextRun(XWPFRun run, Object data) {
            XWPFRun textRun = run;
            if (data instanceof HyperlinkTextRenderData) {
                textRun = createHyperLinkRun(run, data);
            }

            TextRenderData wrapperData = wrapper(data);
            String text = null == wrapperData.getText() ? "" : wrapperData.getText();
            StyleUtils.styleRun(textRun, wrapperData.getStyle());

            boolean lineAtTable= !(data instanceof HyperlinkTextRenderData) && TableTools.isInsideTable(run);

            Pattern pattern = Pattern.compile(SUB_MARK_REG);
            Matcher matcher = pattern.matcher(text);
            int startPos = 0;
            while (matcher.find()) {
                String search = matcher.group();
                int searchPos = text.indexOf(search);
                String value = text.substring(startPos, searchPos);
                if (startPos > 0) {
                    textRun = ((XWPFParagraph) run.getParent()).createRun();
                    StyleUtils.styleRun(textRun, run);
                }
                if (startPos != searchPos) {
                    switch (search) {
                    case SUB_MARK_END :
                        textRun.setSubscript(VerticalAlign.SUBSCRIPT);
                        break;
                    case SUP_MARK_END:
                        textRun.setSubscript(VerticalAlign.SUPERSCRIPT);
                    }
                    renderText(textRun, value, lineAtTable);
                }
                startPos = searchPos + search.length();
            }
            if (startPos == 0) {
                renderText(textRun, text.substring(startPos), lineAtTable);
            } else if (startPos < text.length()) {
                textRun = ((XWPFParagraph) run.getParent()).createRun();
                StyleUtils.styleRun(textRun, run);
                renderText(textRun, text.substring(startPos), lineAtTable);
            }

        }

        private static void renderText(XWPFRun textRun, String text, boolean lineAtTable) {
            String[] split = text.split(REGEX_LINE_CHARACTOR, -1);
            if (split.length > 0) {
                textRun.setText(split[0], 0);
                lineAtTable = split.length > 1 && lineAtTable;
                for (int i = 1; i < split.length; i++) {
                    if (lineAtTable) {
                        textRun.addBreak(BreakType.TEXT_WRAPPING);
                    } else {
                        textRun.addCarriageReturn();
                    }
                    textRun.setText(split[i]);
                }
            }
        }

        private static TextRenderData wrapper(Object obj) {
            return obj instanceof TextRenderData ? (TextRenderData) obj : new TextRenderData(obj.toString());
        }

        private static XWPFRun createHyperLinkRun(XWPFRun run, Object data) {
            XWPFParagraphWrapper paragraph = new XWPFParagraphWrapper((XWPFParagraph) run.getParent());
            XWPFRun hyperLinkRun = paragraph.insertNewHyperLinkRun(run, ((HyperlinkTextRenderData) data).getUrl());
            StyleUtils.styleRun(hyperLinkRun, run);
            run.setText("", 0);
            return hyperLinkRun;
        }

        // word插入字符串带上下标
        public static void addTextWithRun(XWPFRun run, String text) {
            Pattern pattern = Pattern.compile(SUB_MARK_REG);
            Matcher matcher = pattern.matcher(text);
            int startPos = 0;


        }
    }
}
